using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Neovolve.Windows.Forms.Controls;
using System.Collections;

namespace Neovolve.Windows.Forms
{
    /// <summary>
    /// The <see cref="Neovolve.Windows.Forms.WizardForm"/> class is a wizard style form that contains the logic of managing the navigation flow
    /// of <see cref="Neovolve.Windows.Forms.Controls.WizardPage"/> derived controls.
    /// </summary>
    public partial class WizardForm : Form
    {
        #region Declarations

        /// <summary>
        /// Stores the set of wizard pages.
        /// </summary>
        private WizardPageCollection _pages = null;

        /// <summary>
        /// Stores the current page.
        /// </summary>
        private WizardPage _currentPage = null;

        /// <summary>
        /// Stores the navigation history from the start page to the current page.
        /// </summary>
        private Stack<WizardPage> _pageHistory = null;

        /// <summary>
        /// Raised when a navigation is about to occur.
        /// </summary>
        public event EventHandler<WizardFormNavigationEventArgs> Navigating;

        /// <summary>
        /// Raised when a navigation has occurred.
        /// </summary>
        public event EventHandler<WizardFormNavigationEventArgs> Navigated;

        /// <summary>
        /// Stores whether a confirmation message will be displayed when the Cancel navigation is invoked.
        /// </summary>
        private Boolean _confirmCancel = true;

        /// <summary>
        /// Stores a value to indiciate whether the cancel operation should be checked.
        /// </summary>
        private Boolean _ignoreCancelCheck = false;

        /// <summary>
        /// Stores the AutomaticTabOrdering value.
        /// </summary>
        private Boolean _autoTabOrdering = true;

        /// <summary>
        /// Stores the state information for the wizard.
        /// </summary>
        private Dictionary<String, Object> _state = null;

        /// <summary>
        /// Defines a parameterless thread switch delegate.
        /// </summary>
        private delegate void ThreadSwitchDelegate();

        /// <summary>
        /// Defines the delegate used to switch threads when a navigation event is generated.
        /// </summary>
        /// <param name="navigationType">Type of the navigation.</param>
        /// <param name="navigationKey">The navigation key.</param>
        private delegate void GenerateNavigationEventDelegate(WizardFormNavigationTypes navigationType, String navigationKey);

        /// <summary>
        /// Defines the delegate used to close the wizard.
        /// </summary>
        /// <param name="result">The dialog result to assign.</param>
        private delegate void CloseWizardDelegate(DialogResult result);

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="WizardForm"/> class.
        /// </summary>
        public WizardForm()
        {
            InitializeComponent();

            // Create the collections
            _pages = new WizardPageCollection();
            _pageHistory = new Stack<WizardPage>();
            _state = new Dictionary<String, Object>();

            // Hook up the page collection events
            _pages.PageAdded += new WizardPageCollectionPageAddedDelegate(WizardPage_PageAdded);
            _pages.PageRemoved += new WizardPageCollectionPageRemovedDelegate(WizardPage_PageRemoved);
        }

        #endregion

        #region Events

        /// <summary>
        /// Handles the FormClosing event of the WizardForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.FormClosingEventArgs"/> instance containing the event data.</param>
        private void WizardForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // Check if the user wants the cancel to continue
            if ((IgnoreCancelCheck == false)
                && (e.CloseReason == CloseReason.UserClosing)
                && (CanContinueCancel() == false))
            {
                e.Cancel = true;

                return;
            }

            // Notify the current page that it is closing
            if (_currentPage != null)
            {
                _currentPage.OnClosing(new EventArgs());
            }

            // Remove the event handler for the current page
            _currentPage.UpdateWizardSettingsRequired -= new EventHandler(WizardPage_UpdateWizardSettingsRequired);

            // Remove the page collection events
            _pages.PageAdded -= new WizardPageCollectionPageAddedDelegate(WizardPage_PageAdded);
            _pages.PageRemoved -= new WizardPageCollectionPageRemovedDelegate(WizardPage_PageRemoved);
        }

        /// <summary>
        /// Handles the FormClosed event of the WizardForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.FormClosedEventArgs"/> instance containing the event data.</param>
        private void WizardForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            // Notify the current page that it is closed
            if (_currentPage != null)
            {
                _currentPage.OnClosed(new EventArgs());
            }
        }

        /// <summary>
        /// Handles the UpdateWizardSettingsRequired event of the WizardPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void WizardPage_UpdateWizardSettingsRequired(object sender, EventArgs e)
        {
            // Update the state of the wizard UI
            ConfigureCurrentPage();
        }

        /// <summary>
        /// Handles the PageAdded event of the WizardPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.Controls.WizardPageCollectionEventArgs"/> instance containing the event data.</param>
        void WizardPage_PageAdded(object sender, WizardPageCollectionEventArgs e)
        {
            // Assign this form as the owner
            e.Page.SetOwner(this);

            // Check if there is a current page
            if (_currentPage == null)
            {
                // Set this first page as the current page
                CurrentPage = e.Page;
            }
        }

        /// <summary>
        /// Handles the PageRemoved event of the WizardPage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.Controls.WizardPageCollectionEventArgs"/> instance containing the event data.</param>
        void WizardPage_PageRemoved(object sender, WizardPageCollectionEventArgs e)
        {
            // Remove this form as the owner of the page
            e.Page.SetOwner(null);
        }

        /// <summary>
        /// Handles the Click event of the btnNext control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnNext_Click(object sender, EventArgs e)
        {
            GenerateNavigationEvent(WizardFormNavigationTypes.Next);
        }

        /// <summary>
        /// Handles the Click event of the btnPrevious control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnPrevious_Click(object sender, EventArgs e)
        {
            GenerateNavigationEvent(WizardFormNavigationTypes.Previous);
        }

        /// <summary>
        /// Handles the Click event of the btnCancel control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            GenerateNavigationEvent(WizardFormNavigationTypes.Cancel);
        }

        /// <summary>
        /// Handles the Click event of the btnCustom control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnCustom_Click(object sender, EventArgs e)
        {
            GenerateNavigationEvent(WizardFormNavigationTypes.Custom);
        }

        /// <summary>
        /// Handles the Click event of the btnHelp control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void btnHelp_Click(object sender, EventArgs e)
        {
            GenerateNavigationEvent(WizardFormNavigationTypes.Help);
        }

        /// <summary>
        /// Handles the Paint event of the pnlBottom control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.PaintEventArgs"/> instance containing the event data.</param>
        private void pnlBottom_Paint(object sender, PaintEventArgs e)
        {
            // Paint the border
            e.Graphics.DrawLine(System.Drawing.SystemPens.ControlDark, 0, 0, pnlBottom.Width, 0);
            e.Graphics.DrawLine(System.Drawing.SystemPens.ControlLightLight, 0, 1, pnlBottom.Width, 1);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Calculates the tab ordering.
        /// </summary>
        protected virtual void CalculateTabOrdering()
        {
            try
            {
                SetContainerTabOrdering(this, 0);
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Assert(false, "Exception caught in TabOrderManager.SetTabOrder:  " + e.Message);
            }
        }

        /// <summary>
        /// Sets the container tab ordering.
        /// </summary>
        /// <param name="container">The container.</param>
        /// <param name="currentIndex">Index of the current.</param>
        /// <returns>The current tab index of the form.</returns>
        private int SetContainerTabOrdering(Control container, int currentIndex)
        {
            // Assign the new tab index for this item
            container.TabIndex = currentIndex;

            // Increment the index
            currentIndex++;

            ArrayList sortedControls = new ArrayList(container.Controls);
            sortedControls.Sort(new ControlPositionComparer());

            foreach (Control item in sortedControls)
            {
                // Control has children -- recurse.
                currentIndex = SetContainerTabOrdering(item, currentIndex);
            }

            return currentIndex;
        }

        /// <summary>
        /// Generates the navigation event.
        /// </summary>
        /// <param name="navigationType">Type of the navigation.</param>
        internal void GenerateNavigationEvent(WizardFormNavigationTypes navigationType)
        {
            WizardPage page = CurrentPage;
            String navigationKey = String.Empty;

            // Determine the navigation key
            switch (navigationType)
            {
                case WizardFormNavigationTypes.Previous:

                    navigationKey = page.CurrentNavigationSettings.PreviousPageKey;

                    break;

                case WizardFormNavigationTypes.Next:

                    navigationKey = page.CurrentNavigationSettings.NextPageKey;

                    break;

                case WizardFormNavigationTypes.Cancel:

                    navigationKey = page.CurrentNavigationSettings.CancelPageKey;

                    break;

                case WizardFormNavigationTypes.Help:

                    navigationKey = page.CurrentNavigationSettings.HelpPageKey;

                    break;

                case WizardFormNavigationTypes.Custom:

                    navigationKey = page.CurrentNavigationSettings.CustomPageKey;

                    break;

                default:

                    throw new NotSupportedException();
            }

            // Forward the call to the overload
            GenerateNavigationEvent(navigationType, navigationKey);
        }

        /// <summary>
        /// Generates the navigation event.
        /// </summary>
        /// <param name="navigationType">Type of the navigation.</param>
        /// <param name="navigationKey">The navigation key.</param>
        internal void GenerateNavigationEvent(WizardFormNavigationTypes navigationType, String navigationKey)
        {
            // Check if a thread switch is required
            if (this.InvokeRequired == true)
            {
                // Invoke the method on the UI thread
                this.Invoke(new GenerateNavigationEventDelegate(GenerateNavigationEvent), new Object[] { navigationType, navigationKey });

                return;
            }

            WizardPage page = CurrentPage;

            // Check if the type is for a specific key where no key is provided
            if ((navigationType == WizardFormNavigationTypes.NavigationKey)
                && (String.IsNullOrEmpty(navigationKey) == true))
            {
                throw new ArgumentNullException("navigationKey");
            }

            // Invoke the navigation
            OnNavigate(new WizardFormNavigationEventArgs(page, navigationType, navigationKey));
        }

        /// <summary>
        /// Raises the <see cref="E:Navigate"/> event.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void OnNavigate(WizardFormNavigationEventArgs e)
        {
            OnNavigating(e);
            OnNavigated(e);
        }

        /// <summary>
        /// Raises the <see cref="E:Navigating"/> event.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void OnNavigating(WizardFormNavigationEventArgs e)
        {
            // Check if the ignore navigation has been specified
            if (e.NavigationType == WizardFormNavigationTypes.Ignore)
            {
                return;
            }

            // Check if the current page will allow the navigation
            if (e.CurrentPage.CanNavigate(e) == false)
            {
                // The current page will not allow the navigation to continue
                // This will normally be because of validation in the page has failed
                return;
            }

            // Check if anything is handling the event
            if (Navigating != null)
            {
                // Raise the event
                Navigating(this, e);
            }

            switch (e.NavigationType)
            {
                case WizardFormNavigationTypes.Previous:

                    NavigatePrevious(e);

                    break;

                case WizardFormNavigationTypes.Next:

                    NavigateNext(e);

                    break;

                case WizardFormNavigationTypes.Cancel:

                    NavigateCancel(e);

                    break;

                case WizardFormNavigationTypes.Help:

                    NavigateCustom(e);

                    break;

                case WizardFormNavigationTypes.Custom:

                    NavigateCustom(e);

                    break;

                case WizardFormNavigationTypes.NavigationKey:

                    NavigateKey(e);

                    break;

                default:

                    throw new NotSupportedException();
            }
        }

        /// <summary>
        /// Raises the <see cref="E:Navigated"/> event.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void OnNavigated(WizardFormNavigationEventArgs e)
        {
            // Check if anything is handling the event
            if (Navigated != null)
            {
                // Raise the event
                Navigated(this, e);
            }
        }

        /// <summary>
        /// Navigates the previous.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void NavigatePrevious(WizardFormNavigationEventArgs e)
        {
            // Get the navigation key
            String navigationKey = e.NavigationKey;
            WizardPage page = null;

            // Check if there is a navigation key
            if (String.IsNullOrEmpty(navigationKey) == false)
            {
                // Get the next page to navigate to
                page = Pages[navigationKey];
            }
            else
            {
                // Get the previous page in the history
                page = _pageHistory.Peek();
            }

            // Check if there is a next page
            if (page != null)
            {
                // Set the next page
                CurrentPage = page;
            }
        }

        /// <summary>
        /// Navigates the next.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void NavigateNext(WizardFormNavigationEventArgs e)
        {
            // Get the navigation key
            String navigationKey = e.NavigationKey;
            WizardPage page = null;

            // Check if there is a navigation key
            if (String.IsNullOrEmpty(navigationKey) == false)
            {
                // Get the next page
                page = Pages[navigationKey];
            }
            else
            {
                // Get the next page in the collection
                page = Pages.GetNextStoredPage(e.CurrentPage);
            }

            // Check if there is a next page
            if (page != null)
            {
                // Set the next page
                CurrentPage = page;
            }
            else
            {
                // There isn't a page defined for the next action
                // This is the end of the wizard
                CloseWizard(DialogResult.OK);
            }
        }

        /// <summary>
        /// Navigates the cancel.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void NavigateCancel(WizardFormNavigationEventArgs e)
        {
            //Clear the dialog result
            DialogResult = DialogResult.None;

            // Get the navigation key
            String navigationKey = e.NavigationKey;

            // Check if there is a navigation key
            if (String.IsNullOrEmpty(navigationKey) == false)
            {
                // Set the next page
                CurrentPage = Pages[navigationKey];
            }
            else
            {
                // There isn't a page defined for the cancel action

                // Close the wizard
                CloseWizard(DialogResult.Cancel);
            }
        }

        /// <summary>
        /// Navigates the help.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void NavigateHelp(WizardFormNavigationEventArgs e)
        {
            // Get the navigation key
            String navigationKey = e.NavigationKey;

            // Check if there is a navigation key
            if (String.IsNullOrEmpty(navigationKey) == false)
            {
                // Set the next page
                CurrentPage = Pages[navigationKey];
            }
            else
            {
                // There isn't a page defined for the help action

                e.CurrentPage.InvokeHelpNavigation(e);
            }
        }

        /// <summary>
        /// Navigates the custom.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        protected virtual void NavigateCustom(WizardFormNavigationEventArgs e)
        {
            // Get the navigation key
            String navigationKey = e.NavigationKey;

            // Check if there is a navigation key
            if (String.IsNullOrEmpty(navigationKey) == false)
            {
                // Set the next page
                CurrentPage = Pages[navigationKey];
            }
            else
            {
                // There isn't a page defined for the custom action

                e.CurrentPage.InvokeCustomNavigation(e);

                // Check if the navigation details have changed
                if ((e.NavigationType != WizardFormNavigationTypes.Custom)
                    || (String.IsNullOrEmpty(e.NavigationKey) == false))
                {
                    // The page has specified a new navigation value

                    // Call the navigation method again
                    OnNavigate(e);
                }
            }
        }

        /// <summary>
        /// Navigates to the page with the specified key.
        /// </summary>
        /// <param name="e">The <see cref="Neovolve.Windows.Forms.WizardFormNavigationEventArgs"/> instance containing the event data.</param>
        private void NavigateKey(WizardFormNavigationEventArgs e)
        {
            // Set the next page
            CurrentPage = Pages[e.NavigationKey];
        }

        /// <summary>
        /// Removes the current page.
        /// </summary>
        private void RemoveCurrentPage()
        {
            // Check if a thread switch is required
            if (this.InvokeRequired == true)
            {
                // Switch threads
                this.Invoke(new ThreadSwitchDelegate(RemoveCurrentPage), null);

                return;
            }

            // Remove the old page
            pnlPage.Controls.Clear();
        }

        /// <summary>
        /// Populates the current page.
        /// </summary>
        private void PopulateCurrentPage()
        {
            // Check if a thread switch is required
            if (this.InvokeRequired == true)
            {
                // Switch threads
                this.Invoke(new ThreadSwitchDelegate(PopulateCurrentPage), null);

                return;
            }

            // Set up the wizard page
            _currentPage.Dock = DockStyle.Fill;

            ConfigureCurrentPage();

            // Add the page to the form
            pnlPage.Controls.Add(_currentPage);

            // Check if the tab ordering needs to be calculated
            if (AutoTabOrdering == true)
            {
                // Calculate the tab ordering
                CalculateTabOrdering();
            }

            if ((_currentPage.DefaultFocus != null)
                && (_currentPage.DefaultFocus.CanFocus == true))
            {
                _currentPage.DefaultFocus.Focus();
            }
            else if (btnNext.CanFocus == true)
            {
                btnNext.Focus();
            }
        }

        /// <summary>
        /// Configures the current page.
        /// </summary>
        private void ConfigureCurrentPage()
        {
            // Check if a thread switch is required
            if (this.InvokeRequired == true)
            {
                // Switch threads
                this.Invoke(new ThreadSwitchDelegate(ConfigureCurrentPage), null);

                return;
            }

            // Get the current settings for the page
            WizardPageSettings currentSettings = _currentPage.CurrentSettings;

            // Set up the next button
            btnNext.Text = currentSettings.NextButtonSettings.Text;
            btnNext.Enabled = currentSettings.NextButtonSettings.Enabled;
            btnNext.Visible = currentSettings.NextButtonSettings.Visible;

            // Set up the previous button
            btnPrevious.Text = currentSettings.PreviousButtonSettings.Text;
            btnPrevious.Enabled = ((_pageHistory.Count > 0) && (currentSettings.PreviousButtonSettings.Enabled));
            btnPrevious.Visible = currentSettings.PreviousButtonSettings.Visible;

            // Set up the cancel button
            btnCancel.Text = currentSettings.CancelButtonSettings.Text;
            btnCancel.Enabled = currentSettings.CancelButtonSettings.Enabled;
            btnCancel.Visible = currentSettings.CancelButtonSettings.Visible;

            // Set up the help button
            btnHelp.Text = currentSettings.HelpButtonSettings.Text;
            btnHelp.Enabled = currentSettings.HelpButtonSettings.Enabled;
            btnHelp.Visible = currentSettings.HelpButtonSettings.Visible;

            // Set up the custom button
            btnCustom.Text = currentSettings.CustomButtonSettings.Text;
            btnCustom.Enabled = currentSettings.CustomButtonSettings.Enabled;
            btnCustom.Visible = currentSettings.CustomButtonSettings.Visible;
        }

        /// <summary>
        /// Determines whether this instance can continue the cancel operation.
        /// </summary>
        /// <returns>
        /// 	<item>true</item> if this instance can continue the cancel operation.; otherwise, <item>false</item>.
        /// </returns>
        private Boolean CanContinueCancel()
        {
            // Confirm if the user wants to cancel
            if ((ConfirmCancel == true)
                && (MessageBox.Show("Are you sure you want to cancel?", Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No))
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// Closes the wizard.
        /// </summary>
        private void CloseWizard(DialogResult result)
        {
            // Check if a thread switch is required
            if (this.InvokeRequired == true)
            {
                this.Invoke(new CloseWizardDelegate(CloseWizard), new Object[] { result });

                return;
            }

            if (result == DialogResult.OK)
            {
                IgnoreCancelCheck = true;
            }

            this.DialogResult = result;

            // Close the dialog
            Close();
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the pages.
        /// </summary>
        /// <value>The pages.</value>
        [
            Browsable(false)
        ]
        public WizardPageCollection Pages
        {
            get
            {
                return _pages;
            }
        }

        /// <summary>
        /// Gets the current page.
        /// </summary>
        /// <value>The current page.</value>
        [
            Browsable(false)
        ]
        public WizardPage CurrentPage
        {
            get
            {
                // Check if there is a current page
                if (_currentPage != null)
                {
                    // Return the current page
                    return _currentPage;
                }

                // Check if there are any pages
                if (Pages.Count > 0)
                {
                    // Get the first page
                    _currentPage = Pages.GetNextStoredPage(null);

                    // Return the current page
                    return _currentPage;
                }

                // There is no page available
                return null;
            }
            set
            {
                // Check if a value has been supplied
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                // Check that the page exists in the collection
                if (Pages.ContainsValue(value) == false)
                {
                    throw new Exception("Page not found.");
                }

                // Get a reference to the old current page
                WizardPage oldPage = _currentPage;

                // Check if the navigation history contains the specified item
                if (_pageHistory.Contains(value) == true)
                {
                    // We are going back in history

                    // Clear out all the items in the stack that are either the item requested or after the item requested
                    WizardPage previousPage = null;

                    do
                    {
                        previousPage = _pageHistory.Pop();
                    } while (previousPage.Equals(value) == false);
                }
                else if (oldPage != null)
                {
                    // We are going forward in history

                    // Put the old page into the stack
                    _pageHistory.Push(oldPage);
                }

                // Check if there is a current page
                if (oldPage != null)
                {
                    // Remove the event handler for the current page
                    oldPage.UpdateWizardSettingsRequired -= new EventHandler(WizardPage_UpdateWizardSettingsRequired);

                    // Inform the old page that it is being removed
                    oldPage.OnClosing(new EventArgs());
                }

                // Remove the current page
                RemoveCurrentPage();

                // Check if there is an old page
                if (oldPage != null)
                {
                    // Inform the page that it has been removed
                    oldPage.OnClosed(new EventArgs());
                }

                // Store the new current page
                _currentPage = value;

                // Add the event handler for the current page
                _currentPage.UpdateWizardSettingsRequired += new EventHandler(WizardPage_UpdateWizardSettingsRequired);

                // Inform the new page that it is being added
                _currentPage.OnOpening(new EventArgs());

                // Populate the current page
                PopulateCurrentPage();

                // Inform the new page that it has been added
                _currentPage.OnOpened(new EventArgs());
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [confirm cancel].
        /// </summary>
        /// <value><item>true</item> if [confirm cancel]; otherwise, <item>false</item>.</value>
        [
            Category("Behaviour"),
            Description("Determines whether the user will be asked to confirm a cancel action."),
            DefaultValue(true)
        ]
        public Boolean ConfirmCancel
        {
            get { return _confirmCancel; }
            set { _confirmCancel = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether to ignore the cancel check.
        /// </summary>
        /// <value><item>true</item> if the cancel check should be ignored; otherwise, <item>false</item>.</value>
        [
            Browsable(false)
        ]
        private Boolean IgnoreCancelCheck
        {
            get { return _ignoreCancelCheck; }
            set { _ignoreCancelCheck = value; }
        }

        /// <summary>
        /// Gets or sets a value indicating whether automatic tab ordering is used.
        /// </summary>
        /// <value>
        /// 	<item>true</item> if automatic tab ordering is used; otherwise, <item>false</item>.
        /// </value>
        [
            Category("Behaviour"),
            Description("Determines whether control tab ordering is automatically calculated based on positioning."),
            DefaultValue(true)
        ]
        public Boolean AutoTabOrdering
        {
            get { return _autoTabOrdering; }
            set { _autoTabOrdering = value; }
        }

        /// <summary>
        /// Gets the state.
        /// </summary>
        /// <value>The state.</value>
        [
            Browsable(false)
        ]
        public Dictionary<String, Object> State
        {
            get { return _state; }
        }

        #endregion
    }
}